﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.Events;
using NumericalCalculations;
using QLab.Events;
using Engine;
using QLab.Controllers.SolutionExplorer;

namespace QLab.Services
{
	[Export(typeof(ICodeExecutionService))]
	[PartCreationPolicy(CreationPolicy.Shared)]
	public class CodeExecutionService : ICodeExecutionService
	{
		private ICommandHistoryService _commandHistoryService;
		private IEventAggregator _eventAggregator;
		private SolutionExplorerController _solutionExplorerController;

		[ImportingConstructor]
		public CodeExecutionService(IEventAggregator EventAggregator, ICommandHistoryService CommandHistoryService, SolutionExplorerController SolutionExplorerController)
		{
			_eventAggregator = EventAggregator;
			_commandHistoryService = CommandHistoryService;
			_solutionExplorerController = SolutionExplorerController;
		}

		#region Methods

		public void ExecuteCommand(string CommandText)
		{
			string result;
			Dictionary<string, string> varTable;

            // dodao NETKO
            if (string.IsNullOrEmpty(CommandText.Trim()))
            {
                _eventAggregator.GetEvent<CommandExecuted>().Publish("");
                return;
            }
			_eventAggregator.GetEvent<BeforeCommandExecuting>().Publish(CommandText);
			_commandHistoryService.LogCommand(CommandText);

			result = string.Empty;
			varTable = new Dictionary<string, string>();
            try
            {
                EngineManager.Instance.Execute(CommandText, _solutionExplorerController.GetSolutionFunctions(), new List<Dictionary<string, string>>());

                result = EngineManager.Instance.engineVisitor._tempAns[0].ToString();
                varTable.Add("ans", result);
            }
            catch (EngineException ex)
            {
                result = ex.EngineExceptionMessage;
            }
            catch (NumericalCalculationsException ex)
            {
                result = ex.Message;                
            }
            catch (Exception ex)
            {
                result = ex.Message;
            }
			
			foreach (var item in EngineManager.Instance.engineVisitor.VariableTable.Table)
			{
				varTable.Add(item.Key.ToString(), item.Value.ToString());
			}

			_eventAggregator.GetEvent<CommandExecuted>().Publish(result);
			_eventAggregator.GetEvent<CommandExecutedVars>().Publish(varTable);
		}

		#endregion
	}
}
